package cn.edu.cug.cs.gtl.gsm.jdbc.postgres;

import cn.edu.cug.cs.gtl.common.Identifier;
import cn.edu.cug.cs.gtl.gsm.item.ByteArray;
import cn.edu.cug.cs.gtl.gsm.item.DataItem;
import cn.edu.cug.cs.gtl.gsm.item.MetaItem;
import cn.edu.cug.cs.gtl.util.StringUtils;

import java.io.IOException;
import java.sql.*;

public class DataTables {
    private String DATA_TABLE_NAME;
    private String SQL_DROP_DATA_TABLE;
    private String SQL_CREATE_DATA_TABLE;
    private String SQL_DELETE_DATA_TABLE_DATA;
    private String SQL_SELECT_DATA_TABLE_DATA;
    private String SQL_DELETE_ALL_DATA_TABLE_DATA;
    private String SQL_INSERT_DATA_TABLE_DATA;
    private String SQL_UPDATE_DATA_TABLE_DATA;


    protected Connection connection;
    MetaItem metaItem;


    public DataTables(Connection connection,MetaItem metaItem) {
        this.metaItem=metaItem;
        this.connection = connection;
        setCurrentTableOrder(0);
    }

    public void setCurrentTableOrder(int order){
        DATA_TABLE_NAME=metaItem.getBaseName()+".rdb_sm_data_"+metaItem.getBaseName()+"_"+String.valueOf(order);
        SQL_DROP_DATA_TABLE= "DROP TABLE IF EXISTS "+DATA_TABLE_NAME;
        SQL_CREATE_DATA_TABLE= "CREATE TABLE " + DATA_TABLE_NAME + " ( page_identifier  VARCHAR(255) PRIMARY KEY, page_content VARCHAR)";
        SQL_DELETE_DATA_TABLE_DATA= "DELETE FROM " + DATA_TABLE_NAME + " WHERE page_identifier = ?";
        SQL_SELECT_DATA_TABLE_DATA= "SELECT page_content FROM " + DATA_TABLE_NAME + " WHERE page_identifier = ?";
        SQL_DELETE_ALL_DATA_TABLE_DATA= "DELETE FROM " + DATA_TABLE_NAME ;
        SQL_INSERT_DATA_TABLE_DATA= "INSERT INTO " + DATA_TABLE_NAME + " VALUES (?,?)";
        SQL_UPDATE_DATA_TABLE_DATA= "UPDATE " + DATA_TABLE_NAME + " SET page_content = ? WHERE page_identifier=?";
    }

    public boolean create() throws SQLException {
        Statement statement = connection.createStatement();
        boolean r =  statement.execute(SQL_CREATE_DATA_TABLE);
        return r;
    }

    public boolean drop() throws SQLException {
        Statement statement = connection.createStatement();
        boolean r =  statement.execute(SQL_DROP_DATA_TABLE);
        return r;
    }

    public boolean delete(Identifier pageIdentifier) throws SQLException{
        PreparedStatement statement = connection.prepareStatement(SQL_DELETE_DATA_TABLE_DATA);
        statement.setString(1,pageIdentifier.toString());
        boolean r =  statement.execute();
        return r;
    }

    public boolean deleteAll() throws SQLException{
        Statement statement = connection.createStatement();
        boolean r =  statement.execute(SQL_DELETE_ALL_DATA_TABLE_DATA);
        return r;
    }

    public boolean insert(DataItem pageContent) throws SQLException, IOException {
        PreparedStatement statement = connection.prepareStatement(SQL_INSERT_DATA_TABLE_DATA);

        statement.setString(1,pageContent.getPageIdentifier().toString());
        ByteArray byteArray = new ByteArray(pageContent.getPageContent());
        statement.setString(2,byteArray.storeToCompressString());
        boolean r =  statement.execute();
        return r;
    }

    public boolean update(DataItem pageContent) throws SQLException, IOException {
        PreparedStatement statement = connection.prepareStatement(SQL_UPDATE_DATA_TABLE_DATA);
        statement.setString(2,pageContent.getPageIdentifier().toString());
        statement.setString(1,new ByteArray(pageContent.getPageContent()).storeToCompressString());
        boolean r =  statement.execute();
        return r;
    }

    public DataItem select(Identifier pageIdentifier) throws SQLException, IOException {
        PreparedStatement statement = connection.prepareStatement(SQL_SELECT_DATA_TABLE_DATA);
        statement.setString(1,pageIdentifier.toString());
        ResultSet r =  statement.executeQuery();
        String compressZip = null;
        while(r.next()){
            compressZip = r.getString(1);
        }
        if(compressZip!=null) {
            ByteArray byteArray = new ByteArray();
            byteArray.loadFromCompressString(compressZip);
            DataItem dataItem = new DataItem((Identifier) pageIdentifier.clone(), byteArray.getBytes());
            return dataItem;
        }
        else
            return null;
    }

    public boolean exists() throws SQLException{
        String []sa = StringUtils.split(DATA_TABLE_NAME,".");
        return PostgresStorageManager.exists(connection,sa[0],sa[1]);
    }

}
